package de.tu_darmstadt.gdi1.xcom.tests.testcases.students;

import static org.junit.Assert.assertEquals;

import org.junit.Before;
import org.junit.Test;

import de.tu_darmstadt.gdi1.xcom.tests.adapters.XcomTestAdapterLevel2;

/**
 * 
 * Tests if shooting-actions are performed correctly
 * 
 * @author Lukas Schwoebel
 *
 */
public class ShootingTest {
	
	private XcomTestAdapterLevel2 testAdapter;
	
	/**
	 * @throws java.lang.Exception
	 */
	@Before
	public void setUp() throws Exception {
		testAdapter = new XcomTestAdapterLevel2();
	}

	/**
	 * Test method for {@link de.tu_darmstadt.gdi1.xcom.tests.adapters.XcomTestAdapterLevel2#ammoLeft()}.
	 */
	@Test
	public final void testDecrementingWhileShooting() {
		
		testAdapter.loadLevelFromString(TestLevel.testLevel);
		
		testAdapter.changeActivePlayer(4, 2);
		testAdapter.shoot();
		
		// check if actionpoints were decremented correctly
		assertEquals("Shooting should cost 10 actionpoints", TestLevel.actionPoints-10, testAdapter.actionPointsLeft());
		assertEquals("Shooting should cost 1 ammo", 9, testAdapter.ammoLeft());
		
		testAdapter.rotateActivePlayer(false);
		testAdapter.shoot();
		// shooting should have killed the first alien (on 3:2)
		assertEquals("The shoot should have killed the alien on 3:2\n"+testAdapter.returnGamestateAsSavegame(), '.', testAdapter.elementOnPosition(3, 2));
		assertEquals("The shoot should not harm the alien on 2:2\n"+testAdapter.returnGamestateAsSavegame(), 'Z', testAdapter.elementOnPosition(2, 2));
		assertEquals("The shoot should not harm the alien on 2:2\n"+testAdapter.returnGamestateAsSavegame(), 50, testAdapter.healthPointsOfAlien(2, 2));
		testAdapter.shoot();
		// the second alien should have been killed, too
		assertEquals("The shoot should have killed the alien on 2:2\n"+testAdapter.returnGamestateAsSavegame(), '.', testAdapter.elementOnPosition(2, 2));	
	
		assertEquals("After 3 shoots and 1 rotation there should be 44 actionpoints left", 44, testAdapter.actionPointsLeft());
		assertEquals("After 3 shoots there should be 7 ammo left", 7, testAdapter.ammoLeft());
		
		testAdapter.endTurn();
		assertEquals("After end of the turn the player should still have 7 ammo", 7, testAdapter.ammoLeft());
		
	}
	
	/**
	 * Test method for {@link de.tu_darmstadt.gdi1.xcom.tests.adapters.XcomTestAdapterLevel2#healthPointsOfAlien()}.
	 */
	@Test
	public final void testDifferentDamage() {
		
		testAdapter.loadLevelFromString(TestLevel.saveGame1);
		testAdapter.changeActivePlayer(4, 2);
		
		// first shoot alien
		testAdapter.rotateActivePlayer(false);
		testAdapter.rotateActivePlayer(false);
		testAdapter.shoot();
		assertEquals("After shooting, the alien on 3:2 should have 1 healthpoints left:\n"+testAdapter.returnGamestateAsSavegame(),
				1, testAdapter.healthPointsOfAlien(3, 2));
		// now shoot again
		testAdapter.shoot();
		assertEquals("After shooting twice, the alien on 3:2 should be dead:\n"+testAdapter.returnGamestateAsSavegame(),
				'.', testAdapter.elementOnPosition(3, 2));


		// reload savegame
		testAdapter.loadLevelFromString(TestLevel.saveGame1);
		testAdapter.changeActivePlayer(4, 2);
		
		// now attack alien
		testAdapter.rotateActivePlayer(false);
		testAdapter.rotateActivePlayer(false);
		testAdapter.performActionForActivePlayer();
		assertEquals("After attacking, the alien on 3:2 should have 16 healthpoints left:\n"+testAdapter.returnGamestateAsSavegame(),
				16, testAdapter.healthPointsOfAlien(3, 2));
		testAdapter.performActionForActivePlayer();
		assertEquals("After attacking twice, the alien on 3:2 should be dead:\n"+testAdapter.returnGamestateAsSavegame(),
				'.', testAdapter.elementOnPosition(3, 2));
	}

	/**
	 * Test method for {@link de.tu_darmstadt.gdi1.xcom.tests.adapters.XcomTestAdapterLevel2#ammoLeft()}.
	 */
	@Test
	public final void testLongDistanceShoot() {

		// load savegame
		testAdapter.loadLevelFromString(TestLevel.saveGame1);
		
		testAdapter.changeActivePlayer(4, 6);
		testAdapter.rotateActivePlayer(true);
		testAdapter.performActionForActivePlayer();
		testAdapter.rotateActivePlayer(true);
		
		// now player is facing to alien at 3:2
		testAdapter.shoot();
		assertEquals("After a shoot, the alien at 3:2 should be dead", '.', testAdapter.elementOnPosition(3, 2));
		
		// shot through a wall should not be possible
		testAdapter.changeActivePlayer(2, 5);
		testAdapter.rotateActivePlayer(true);
		testAdapter.shoot();
		assertEquals("The shoot should not harm the alien on 2:2 behind the wall\n"+testAdapter.returnGamestateAsSavegame(), 'Z', testAdapter.elementOnPosition(2, 2));
		assertEquals("The shoot should not harm the alien on 2:2 behind the wall\n"+testAdapter.returnGamestateAsSavegame(), 50, testAdapter.healthPointsOfAlien(2, 2));
		
		
	}
}
